package chen.web.event;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class EventSupport {

	private Map<String, List<EventListener<?>>> ListenerMapping = new ConcurrentHashMap<String, List<EventListener<?>>>();
	private static Log log = LogFactory.getLog(EventSupport.class);
	
	public <T extends Event> void fireEvent(T event){
		List<EventListener<?>> listenerList = ListenerMapping.get(event.getClass().getName());
		if(listenerList != null){
			for(EventListener<?> listener : listenerList){
				((EventListener<T>)listener).listen(event);
			}	
		}
	}
	
	public synchronized <T extends Event> void addListener(EventListener<T> listener){
		Type[] types = listener.getClass().getGenericInterfaces();
		for(Type type : types){
			if(EventListener.class.equals(((ParameterizedType) type).getRawType())){
				Class<T> clazz = (Class<T>)((ParameterizedType)type).getActualTypeArguments()[0];
				List<EventListener<?>> listenerList = ListenerMapping.get(clazz.getName());
				if(listenerList == null){
					listenerList = Collections.synchronizedList(new ArrayList<EventListener<?>>());
					ListenerMapping.put(clazz.getName(), listenerList);
				}
				log.debug("add event listenner: " + listener.getClass());
				listenerList.add(listener);
			}
		}
	}
}
